package com.gqh.weather.service;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.gqh.weather.domain.dto.QuestionSubIdInfo;
import com.gqh.weather.domain.dto.StudentUploadAnswerData;
import com.gqh.weather.domain.dto.StudentInfoDTO;
import com.gqh.weather.domain.dto.TaskSchedule;
import com.gqh.weather.domain.dto.PaperInfo;
import com.gqh.weather.domain.entity.PcSubtask;
import com.gqh.weather.domain.entity.Student;
import com.gqh.weather.domain.entity.Paper;
import com.gqh.weather.domain.entity.Question;
import com.gqh.weather.domain.entity.School;
import com.gqh.weather.domain.entity.Task;
import com.gqh.weather.mapper.PcSubtaskMapper;
import com.gqh.weather.mapper.StudentMapper;
import com.gqh.weather.mapper.PaperMapper;
import com.gqh.weather.mapper.QuestionMapper;
import com.gqh.weather.mapper.SchoolMapper;
import com.gqh.weather.mapper.TaskMapper;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.gqh.weather.domain.entity.StudentAnswer;
import com.gqh.weather.mapper.StudentAnswerMapper;
import com.gqh.weather.service.PaperService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @description 考试管理服务类
 * @author AI
 * @date 2025-09-21
 */
@Slf4j
@Service
public class ExamService {

    @Autowired
    private PcSubtaskMapper pcSubtaskMapper;
    
    @Autowired
    private StudentMapper studentMapper;
    
    @Autowired
    private PaperMapper paperMapper;
    
    @Autowired
    private QuestionMapper questionMapper;
    
    @Autowired
    private SchoolMapper schoolMapper;
    
    @Autowired
    private StudentAnswerMapper studentAnswerMapper;
    
    @Autowired
    private TaskMapper taskMapper;
    
    @Autowired
    private PaperService paperService;
    
    // 用于JSON解析
    private static final ObjectMapper objectMapper = new ObjectMapper();

    /**
     * 学生上传答案
     *
     * @param paperName 试卷名称
     * @param examId 考试ID
     * @param studentNo 学号
     * @param List<StudentUploadAnswerData> 答案数据
     * @throws Exception 异常信息
     */
    public void studentUploadAnswer(String paperName, Integer examId, String studentNo, List<StudentUploadAnswerData> answerDatas) throws Exception {
        // 检查PC子任务是否存在
        PcSubtask subtaskInfo = pcSubtaskMapper.selectById(examId);
        if (subtaskInfo == null) {
            throw new Exception("任务id不存在");
        }
        
        // 查找学生信息
        LambdaQueryWrapper<Student> studentWrapper = new LambdaQueryWrapper<>();
        studentWrapper.eq(Student::getStudentNo, studentNo);
        studentWrapper.eq(Student::getTaskId, subtaskInfo.getTaskPid());
        Student stuInfo = studentMapper.selectOne(studentWrapper);
        if (stuInfo == null) {
            throw new Exception("找不到该学生");
        }
        
        // 查找试卷信息
        LambdaQueryWrapper<Paper> paperWrapper = new LambdaQueryWrapper<>();
        paperWrapper.eq(Paper::getName, paperName);
        Paper paperInfo = paperMapper.selectOne(paperWrapper);
        if (paperInfo == null) {
            throw new Exception("试卷ID 不存在");
        }
        
        // 检查时间范围
        if (subtaskInfo.getSchedule() != null && !subtaskInfo.getSchedule().isEmpty()) {
            try {
                // 解析schedule字段中的TaskSchedule列表
                List<TaskSchedule> schedules = objectMapper.readValue(
                    subtaskInfo.getSchedule(), 
                    new TypeReference<List<TaskSchedule>>() {}
                );
                
                // 查找对应试卷的时间范围
                TaskSchedule targetSchedule = null;
                for (TaskSchedule schedule : schedules) {
                    if (schedule.getPaperId() != null && schedule.getPaperId().equals(paperInfo.getId())) {
                        targetSchedule = schedule;
                        break;
                    }
                }

                if (targetSchedule == null) {
                    throw new Exception("试卷不在该任务范围内");
                }
                
                // 如果找到了对应试卷的时间范围，检查是否在时间范围内
                int currentTime = (int) (System.currentTimeMillis() / 1000);
                
                // 检查是否在开始时间之后
                if (targetSchedule.getStime() != null && currentTime < targetSchedule.getStime()) {
                    throw new Exception("考试尚未开始");
                }
                
                // 检查是否在结束时间之前
                if (targetSchedule.getEtime() != null && currentTime > targetSchedule.getEtime() + 60) {
                    throw new Exception("考试已结束");
                }
            } catch (JsonProcessingException e) {
                log.warn("解析PC子任务schedule字段失败: {}", e.getMessage());
            }
        }
        
        // 获取题目ID列表
        List<Integer> qids = answerDatas.stream()
                .map(StudentUploadAnswerData::getQid)
                .collect(Collectors.toList());
        
        // 获取题目列表
        List<Question> questions = questionMapper.selectByIds(qids);
        
        // 检查题目数量是否匹配
        if (qids.size() != questions.size()) {
            throw new Exception("答题数与后台题目不匹配!");
        }
        
        // 处理综合题型(qtype=100)的答案
        List<StudentUploadAnswerData> processedAnswers = processComprehensiveQuestions(answerDatas, questions);
        
        // 将处理后的答案转换为JSON字符串
        String processedAnswer = objectMapper.writeValueAsString(processedAnswers);
        
        // 获取学校信息以获取城市码
        School schoolInfo = schoolMapper.selectById(stuInfo.getSchoolId());
        String citycode = schoolInfo != null ? schoolInfo.getCitycode() : null;

        // 检查表中是否已有该学生、任务、试卷的记录
        LambdaQueryWrapper<StudentAnswer> existingAnswerWrapper = new LambdaQueryWrapper<>();
        existingAnswerWrapper.eq(StudentAnswer::getStudentId, stuInfo.getId());
        existingAnswerWrapper.eq(StudentAnswer::getTaskId, stuInfo.getTaskId());
        existingAnswerWrapper.eq(StudentAnswer::getPaperId, paperInfo.getId());
        existingAnswerWrapper.eq(StudentAnswer::getIsDeleted, 0); // 只查找未删除的记录
        boolean exists = studentAnswerMapper.exists(existingAnswerWrapper);

        // 如果已存在记录，则抛出异常
        if (exists) {
            throw new Exception("该学生在此任务和试卷中已存在答题记录");
        }
        
        // 创建学生答案记录
        StudentAnswer studentAnswer = new StudentAnswer();
        studentAnswer.setStudentId(stuInfo.getId());
        studentAnswer.setTaskId(stuInfo.getTaskId());
        studentAnswer.setPaperId(paperInfo.getId());
        studentAnswer.setPaperType(paperInfo.getType());
        studentAnswer.setSchoolId(stuInfo.getSchoolId());
        studentAnswer.setCitycode(citycode);
        studentAnswer.setAnswer(processedAnswer);
        
        // 保存学生答案
        studentAnswerMapper.insert(studentAnswer);
        log.info("学生上传答案成功，考试ID: {}, 学号: {}", examId, studentNo);
    }
    /**
     * 学生上传答案
     *
     * @param paperName 试卷名称
     * @param examId 考试ID
     * @param studentNo 学号
     * @param answer 答案数据
     * @throws Exception 异常信息
     */
    public void studentUploadAnswer(String paperName, Integer examId, String studentNo, String answer) throws Exception {
        // 解析答案数据
        List<StudentUploadAnswerData> answerDatas = parseAnswerData(answer);

        studentUploadAnswer(paperName, examId, studentNo, answerDatas);
    }

    /**
     * 解析答案数据
     *
     * @param answer 答案JSON字符串
     * @return 答案数据列表
     * @throws JsonProcessingException JSON解析异常
     */
    private List<StudentUploadAnswerData> parseAnswerData(String answer) throws JsonProcessingException {
        if (!StringUtils.hasText(answer)) {
            return new ArrayList<>();
        }
        return objectMapper.readValue(answer, new TypeReference<List<StudentUploadAnswerData>>() {});
    }
    
    /**
     * 处理综合题型的答案
     *
     * @param answerDatas 原始答案数据
     * @param questions 题目列表
     * @return 处理后的答案数据
     * @throws JsonProcessingException JSON解析异常
     */
    private List<StudentUploadAnswerData> processComprehensiveQuestions(
            List<StudentUploadAnswerData> answerDatas, 
            List<Question> questions) throws JsonProcessingException {
        
        List<StudentUploadAnswerData> processedAnswers = new ArrayList<>();
        
        // 创建题目ID到题目的映射
        java.util.Map<Integer, Question> questionMap = questions.stream()
                .collect(Collectors.toMap(Question::getId, question -> question));
        
        for (StudentUploadAnswerData answerData : answerDatas) {
            Integer qid = answerData.getQid();
            Question question = questionMap.get(qid);
            
            // 如果题目不存在或不是综合题型，直接添加到结果中
            if (question == null || question.getQtype() != 100) {
                processedAnswers.add(answerData);
                continue;
            }
            
            // 如果是综合题型但没有子题目，跳过
            if (question.getSubid() == null || question.getSubid().isEmpty() || "[]".equals(question.getSubid())) {
                processedAnswers.add(answerData);
                continue;
            }
            
            // 解析子题目信息
            List<QuestionSubIdInfo> subIdInfos = objectMapper.readValue(
                    question.getSubid(), 
                    new TypeReference<List<QuestionSubIdInfo>>() {});
            
            // 分割答案
            String[] answers = answerData.getAnswer().split(",");
            
            // 检查答案数量是否与子题目数量匹配
            if (answers.length != subIdInfos.size()) {
                throw new RuntimeException("题目" + qid + "答案与子题目不匹配");
            }
            
            // 为每个子题目创建答案记录
            for (int i = 0; i < answers.length; i++) {
                String subAnswer = answers[i];
                // 如果子答案为空，跳过
                if (subAnswer == null || subAnswer.isEmpty()) {
                    continue;
                }
                
                StudentUploadAnswerData subAnswerData = new StudentUploadAnswerData();
                subAnswerData.setQid(subIdInfos.get(i).getId());
                subAnswerData.setAnswer(subAnswer);
                processedAnswers.add(subAnswerData);
            }
        }
        
        return processedAnswers;
    }
    
    /**
     * 学生登录
     *
     * @param studentNo 学籍号
     * @param studentName 学生姓名
     * @return 学生信息
     * @throws Exception 异常信息
     */
    public StudentInfoDTO studentLogin(String studentNo, String studentName) throws Exception {
        // 查找学生信息（可能有多个，属于不同任务）
        LambdaQueryWrapper<Student> studentWrapper = new LambdaQueryWrapper<>();
        studentWrapper.eq(Student::getStudentNo, studentNo);
        studentWrapper.eq(Student::getName, studentName);
        List<Student> studentList = studentMapper.selectList(studentWrapper);
        
        // 如果学生不存在
        if (studentList.isEmpty()) {
            throw new Exception("学号或姓名错误");
        }
        
        // 获取当前时间戳
        int currentTime = (int) (System.currentTimeMillis() / 1000);
        
        // 为每个学生创建StudentInfoDTO，形成列表
        List<StudentInfoDTO> studentInfoDTOList = new ArrayList<>();
        
        for (Student student : studentList) {
            // 获取学校信息
            School schoolInfo = schoolMapper.selectById(student.getSchoolId());
            if (schoolInfo == null || student.getSchoolId() == 0) {
                // 如果学校信息不存在，跳过这个学生记录
                continue;
            }
            
            // 获取任务信息
            Task taskInfo = null;
            if (student.getTaskId() != null && student.getTaskId() > 0) {
                taskInfo = taskMapper.selectById(student.getTaskId());
            }

            if (taskInfo == null || taskInfo.getState() != 1) {
                continue;
            }
            
            // 构造学生信息DTO
            StudentInfoDTO studentInfoDTO = new StudentInfoDTO();
            studentInfoDTO.setName(student.getName());
            studentInfoDTO.setSchoolId(student.getSchoolId());
            studentInfoDTO.setStudentNo(student.getStudentNo());
            studentInfoDTO.setSex(student.getSex());
            studentInfoDTO.setGrade(student.getGrade());
            studentInfoDTO.setTaskId(student.getTaskId());
//            studentInfoDTO.setPicUrl(student.getPicUrl());
            studentInfoDTO.setSchoolName(schoolInfo.getName());
            studentInfoDTO.setTaskName(taskInfo.getName());
            
            // 获取PC子任务信息和试卷信息
            LambdaQueryWrapper<PcSubtask> pcSubtaskWrapper = new LambdaQueryWrapper<>();
            pcSubtaskWrapper.eq(PcSubtask::getTaskPid, student.getTaskId());
            PcSubtask pcSubtask = pcSubtaskMapper.selectOne(pcSubtaskWrapper, false);

            if (pcSubtask == null || pcSubtask.getState() != 1) {
                continue;
            }
            
            if (pcSubtask != null && pcSubtask.getSchedule() != null && !pcSubtask.getSchedule().isEmpty()) {
                studentInfoDTO.setExamId(pcSubtask.getId());
                try {
                    // 解析schedule字段中的TaskSchedule列表
                    List<TaskSchedule> schedules = objectMapper.readValue(
                        pcSubtask.getSchedule(), 
                        new TypeReference<List<TaskSchedule>>() {}
                    );
                    
                    // 按照stime排序（简化版）
                    schedules.sort((s1, s2) -> s1.getStime().compareTo(s2.getStime()));
                    
                    // 查找符合时间范围的试卷
                    for (TaskSchedule schedule : schedules) {
                        // 检查考试是否已结束
                        if (schedule.getEtime() != null && schedule.getEtime() < currentTime) {
                            // 考试已结束，跳过
                            continue;
                        }
                        
                        if (schedule.getPaperId() != null) {
                            
                            // 检查是否已有答题记录
                            LambdaQueryWrapper<StudentAnswer> answerWrapper = new LambdaQueryWrapper<>();
                            answerWrapper.eq(StudentAnswer::getTaskId, student.getTaskId());
                            answerWrapper.eq(StudentAnswer::getStudentId, student.getId());
                            answerWrapper.eq(StudentAnswer::getPaperId, schedule.getPaperId());
                            answerWrapper.eq(StudentAnswer::getIsDeleted, 0);
                            answerWrapper.orderByDesc(StudentAnswer::getId);
                            StudentAnswer existingAnswer = studentAnswerMapper.selectOne(answerWrapper, false);
                            
                            // 如果已有答题记录，跳过
                            if (existingAnswer != null) {
                                continue;
                            }
                            
                            // 使用PaperService的getPaperInfo方法获取试卷信息
                            try {
                                PaperInfo paperInfo = paperService.getPaperInfo(schedule.getPaperId()).getData();
                                if (paperInfo != null) {
                                    // 设置试卷的时间信息
                                    paperInfo.setStime(schedule.getStime());
                                    paperInfo.setEtime(schedule.getEtime());
                                    
                                    // 设置试卷信息到学生信息DTO中
                                    studentInfoDTO.setPaperInfo(paperInfo);

                                    // 没到时间不显示完整试卷
                                    if (currentTime < schedule.getStime()) {
                                        paperInfo.setData(null);
                                        paperInfo.setDataInfo(null);
                                    }
                                }
                            } catch (Exception e) {
                                log.warn("获取试卷信息失败: {}", e.getMessage());
                            }

                            // 将构造好的DTO添加到列表中
                            studentInfoDTOList.add(studentInfoDTO);
                            
                            break; // 找到第一个符合时间范围的试卷就退出循环
                        }
                    }
                } catch (JsonProcessingException e) {
                    log.warn("解析PC子任务schedule字段失败: {}", e.getMessage());
                }
            }
            
            
        }
        
        // 如果没有构造出任何DTO，抛出异常
        if (studentInfoDTOList.isEmpty()) {
            throw new Exception("没有考试");
        }
        
        // 如果只有一个DTO，直接返回
        if (studentInfoDTOList.size() == 1) {
            return studentInfoDTOList.get(0);
        }
        
        // 如果有多个DTO，排序找到距离stime最近的考试记录
        studentInfoDTOList.sort((s1, s2) -> s1.getPaperInfo().getStime().compareTo(s2.getPaperInfo().getStime()));
        
        // 返回距离stime最近的考试记录
        return studentInfoDTOList.get(0);
    }
}